package combat;

import java.awt.Point;
import java.awt.Rectangle;

/**
 * ConcreteClass for Strategy that handles bullets conflicting with a barrier
 * @author Chris
 *
 */
public class BarrierConflict implements ConflictStrategy {

	@Override
	/**
	 *  on a barrier, i bounce.  this is the tricky one, since my bounce
	 *  depends on the direction i'm heading and the direction of the barrier
	 */
	public void execute(Sprite enemy, Bullet bullet) {
		  //get the direction for checking purposes
        int dir = bullet.image.getDirection();
        
        //first, we check to see if we are heading in a "straight" or dead-on
        //direction, in which case we simply reverse direction.
        if( (dir == DirectionalImage.North) || 
            (dir == DirectionalImage.South) ||
            (dir == DirectionalImage.East) ||
            (dir == DirectionalImage.West) )
        {        
            //this factors in the "0" default direction
            bullet.image.setDirection( (( dir + 3 ) % 8) + 1 ); 
            bullet.board.registerMove( bullet.image, enemy );
        }
        else
        {
            //otherwise, we are moving diagonally, and so we need to figure our
            //next direction by which part of the box we hit.  To do that, we 
            //get the bounding box of the barrier and check some points
        	Rectangle barrierBox = enemy.getBoundingBox();
        	
            Point barUpperLeft = barrierBox.getLocation();
            Point barLowerRight = new Point( barUpperLeft.x + barrierBox.width, 
                                             barUpperLeft.y + barrierBox.height );
            Point barUpperRight = new Point( barUpperLeft.x, 
                                             barUpperLeft.y + barrierBox.height );
            Point barLowerLeft = new Point( barUpperLeft.x + barrierBox.width, 
                                            barUpperLeft.y );
            
            //and we need my position
            Rectangle bulletBox = bullet.getBoundingBox(); 
            Point bulUpperLeft = bulletBox.getLocation();
            Point bulLowerRight = new Point( bulUpperLeft.x + bulletBox.width, 
                                             bulUpperLeft.y + bulletBox.height );
            Point bulUpperRight = new Point( bulUpperLeft.x, 
                                             bulUpperLeft.y + bulletBox.height );
            Point bulLowerLeft = new Point( bulUpperLeft.x + bulletBox.width, 
                                            bulUpperLeft.y );
        	
            //now, we decide which way to bounce case by case
            
            //Basically, the bouncing algorithm checks first to see which
            //we're heading, then from that tries to determine if I crossed
            //the barrier from on the x plane or the y plane (since in each 
            //direction it is only possible to cross each plae one way).
            //this will work along as I'm not moving in real large incements
            //(i.e. real fast)
            
            //northern movement
            if( (dir == DirectionalImage.NorthWest) )
            {
                if( (bulUpperLeft.x <= barLowerRight.x ) &&
                    (!(bullet.lastUpL.x >= barLowerRight.x)) )
                {
                    bullet.image.setDirection( DirectionalImage.SouthWest );
                }
                else if( (bulUpperLeft.y <= barLowerRight.y ) )
                {
                    bullet.image.setDirection( DirectionalImage.NorthEast );
                }
                else
                {
                    System.err.println( "ERROR - NW" );
                }
            }
            
            if( (dir == DirectionalImage.NorthEast) )
            {
                if( (bulUpperLeft.x >= barLowerRight.x ) &&
                    (!(bullet.lastUpL.x >= barLowerRight.x)) )
                {
                    bullet.image.setDirection( DirectionalImage.SouthEast );
                }
                else if( (bulLowerRight.y >= barUpperLeft.y ) )
                {
                    bullet.image.setDirection( DirectionalImage.NorthWest );
                }
                else
                {
                    System.err.println( "ERROR - NE" );
                }
            }
            
            //now for southernly movement
            if( (dir == DirectionalImage.SouthWest) )
            {
                if( (bulLowerRight.x <= barUpperLeft.x ) &&
                    (!(bullet.lastLowR.x <= barUpperLeft.x)) )
                {
                    bullet.image.setDirection( DirectionalImage.NorthWest );
                }
                else if( (bulUpperLeft.y <= barLowerRight.y ) )
                {
                    bullet.image.setDirection( DirectionalImage.SouthEast );
                }
                else
                {
                    System.err.println( "ERROR - SW" );
                }
            }
            
            if( (dir == DirectionalImage.SouthEast) )
            {
                if( (bulLowerRight.x >= barUpperLeft.x ) &&
                    (!(bullet.lastLowR.x <= barUpperLeft.x)) )
                {
                    bullet.image.setDirection( DirectionalImage.NorthEast );
                }
                else if( (bulLowerRight.y >= barUpperLeft.y ) )
                {
                    bullet.image.setDirection( DirectionalImage.SouthWest );
                }
                else
                {
                    System.err.println( "ERROR - SE" );
                }
            }
            
            //register the move with the board
            bullet.board.registerMove( bullet.image, enemy  );
        }
	}

}
